<template>
  <div>
    <div class="modal-body">
      <div class="steps" v-if="!isShowUpdateCode">
        <a-steps size="small" :current="1" :status="'process'">
          <a-step :title="$t('languages.Apps.UploadFile')"></a-step>
          <a-step :title="$t('languages.Apps.VerifyFile')">
            <a-icon v-if="!isValidated" type="loading" slot="icon"/>
          </a-step>
          <a-step :title="$t('languages.Apps.Import')"></a-step>
        </a-steps>
      </div>

      <div class="file-validate">
        <!-- 文件校验通过 -->
        <div class="validate-box" v-if="validateStatus === 'ok' && !isShowUpdateCode">
          <div class="file-status">
            <i class="icon aufontAll h-icon-all-check-circle file-status-icon"></i>
            <span class="file-status-txt">{{ $t('languages.Apps.DocumentChecked') }}</span>
          </div>
          <p style="margin-top:8px;color: #999;">模型编码无重复</p>
        </div>

        <update-code
          v-else-if="isShowUpdateCode"
          ref="updateCode"
          :list="list"
          :repeated="repeated"
          :isCoverable="isCoverable"
          @inputChange="inputChange"
        >
        </update-code>

        <error-message
          v-else
          :validateStatus="validateStatus"
          :isDataModelError="isDataModelError"
          :isSubTableRepeat="isSubTableRepeat"
          :errorInfo="errorInfo"
          :warnInfoList="warnInfoList"
          :repeated="repeated"
          :isCoverable="isCoverable"
        >
        </error-message>
      </div>

    </div>

    <div class="modal-footer">
      <!-- 1. 校验成功 -->
      <template v-if="validateStatus === 'ok' && !isShowUpdateCode">
        <a-button 
          v-if="!isShowUpdateCode" 
          @click="updateCode">
          {{ $t('languages.Apps.EditCode') }}
        </a-button>
        <!-- 导入 -->
        <a-button
          type="primary"
          @click="doImport">
          {{ $t('languages.Apps.Import') }}
        </a-button>
      </template>

      <!-- 2. 编码重复 -->
      <template v-if="validateStatus === 'repeat' && !isShowUpdateCode && !isCoverable">
        <!-- 修改编码 -->
        <template>
          <a-button 
            v-if="!isShowUpdateCode" 
            @click="updateCode">
            {{ $t('languages.Apps.EditCode') }}
          </a-button>
        </template>
        <!-- 导入并覆盖 -->
        <a-button
            v-if="showCover"
            type="primary"
            @click="importAndCover">{{ $t('languages.Apps.ImportAndCover') }}
        </a-button>
        
      </template>

      <!-- 3. 对象不存在错误 -->
      <!-- 取消 -->
      <template v-if="validateStatus === 'referCode'  && !isShowUpdateCode">
        <a-button @click="handleCancel"> 
          {{$t('languages.Apps.Cancel')}}
        </a-button>

        <a-button 
          v-if="!isShowUpdateCode" 
          @click="updateCode">
          {{ $t('languages.Apps.EditCode') }}
        </a-button>

        <a-button
          type="primary"
          @click="doImport">{{ $t('languages.Apps.Import') }}
        </a-button>
      </template>

      <!-- 4. 文件错误 -->
      <template v-if="validateStatus === 'error'  && !isShowUpdateCode">
        <a-button
          type="primary"
          @click="prevStep">{{ $t('languages.Apps.PreStep') }}
      </a-button>
      </template>

      <!-- 5. 修改编码界面 -->
      <template v-if="isShowUpdateCode">
        <!-- 返回 -->
        <a-button
          @click="returnClick"
          >{{ $t('languages.Apps.return') }}
        </a-button>

        <!-- 保存并返回 -->
        <a-button
          type="primary"
          @click="returnAndSaveClick"
          >{{ $t('languages.Apps.SaveAndReturn') }}
        </a-button>
      </template>

      <!-- 6. 导入并覆盖界面 -->
      <template v-if="isCoverable && !isShowUpdateCode">
        <!-- 返回 -->
        <a-button
          @click="() => {
            this.isCoverable = false
          }"
          >{{ $t('languages.Apps.return') }}
        </a-button>

        <a-button 
          @click="updateCode">
          {{ $t('languages.Apps.EditCode') }}
        </a-button>

        <!-- 继续导入 -->
        <a-button
          type="primary"
          @click="doImport"
          >继续导入
        </a-button>
      </template>
    </div>
  </div>
</template>

<script lang="ts">
import AppsApi from '@/apis/apps';
import * as FileValidateNS from "@/typings/app-error";
import { Icon, Input } from "@h3/antd-vue";
import { Component, Prop, Vue, Watch } from "vue-property-decorator";
import ErrorMessage from './errorMessage.vue';
import UpdateCode from './update-code.vue';







@Component({
  name: "FileValidate",
  components: {
    AIcon: Icon,
    AInput: Input,
    UpdateCode,
    ErrorMessage,
  }
})
export default class FileValidate extends Vue {
  @Prop() uploadResult!: any;

  /**
   * 控制逻辑
   */
  validateStatus: string = ''; // 校验状态

  isValidated: boolean = false; // 是否校验完成， loading图标

  isDelete: boolean = false;  //是否回收站模型

  isImportDataRule: any = null; // 是否导入数据规则

  repeated: boolean = false; // 模型编码重复

  isCoverable: boolean = false; // 是否覆盖

  isShowUpdateCode: boolean = false;  //是否展示修改编码按钮

  canSave: boolean = false;   //修改编码界面是否展示保存并返回按钮

  /**
   * 中间数据存储
   */
  bizFormsList: any[] = [] // 表单

  workflowsList: any[] = [] // 流程

  codeList:any[] = []  //模型

  sheetList: any[] = [];  //子表

  warnInfoList: any = {
    repeatMsg: [],
    warnMsg: [],
  };  //错误列表

  subSchemaCodes: any = null; // 记录子表编码重复

  appFunctionModel: any = null; // 所在目录

  appPackageModel: any = null; // 所在应用

  oldSheetList:any[] = [];   //修改编码界面，回退编码

  sheetItemDate: any = new Map();  //子表修改编码相关

  /**
   * 其他
   */

  fileName: string = ''  //文件名，由上传界面收集

  errorType: number = -1; // 导入错误对应的类型

  errorInfo: string = ''; // 数据项错误时的错误文案

  subSchemaNames: any = null; // 业务模型子表名称

  get list() {
    return {
      codeList: this.codeList,
      sheetList: this.sheetList,
      bizFormsList: this.bizFormsList,
      workflowsList: this.workflowsList,
    }
  }

  get isShowCodeRepeat() {
    // 与是否显示修改编码互斥
    return !this.isShowUpdateCode;
  }

  // 是否 当前应用
  get isPackageModel() {
    console.log('I am in')
    return this.appPackageModel && this.$route.params.appCode === this.appPackageModel.code || false;
  }

  get isDataModelError() {
    return (
      this.errorType === FileValidateNS.FileValidateTypes.DataItemTypeError
    );
  }

  get isSubTableRepeat() {
    return (
      this.errorType === FileValidateNS.FileValidateTypes.SubTableCodeRepeat
    );
  }

  get errorTxt() {
    switch (this.errorType) {
      case FileValidateNS.FileValidateTypes.FileFormateError:
        return this.$t("languages.Apps.FileFormateError");
      case FileValidateNS.FileValidateTypes.VersionError:
        return this.$t("languages.Apps.VersionError");
      case FileValidateNS.FileValidateTypes.SystemError:
        return this.$t("languages.Apps.SystemError");
      case FileValidateNS.FileValidateTypes.RepeatCode:
        return this.$t("languages.Apps.RepeatCode");
      case FileValidateNS.FileValidateTypes.SubTableCodeRepeat:
        return this.$t("languages.Apps.RepeatCode");
      case FileValidateNS.FileValidateTypes.RelativeModelNotImported:
        return this.$t("languages.Apps.RelativeModelNotImported");
      case FileValidateNS.FileValidateTypes.SubFlowNeedBeImportedFirst:
        return this.$t("languages.Apps.SubFlowNeedBeImportedFirst");
      case 10005:
        return this.errorInfo;
      case 50000:
        return '服务异常';
      default:
        return null;
    }
  }

  mounted() {
    this.fileName = this.uploadResult.fileName

    this.checkPackage('', this.fileName, false);
  }

  /**
   * 获取修改后的编码list
   * */ 
  getCodeList(){
    return (this.$refs.updateCode as any).getCodeList();
  }

  /**
   * 文件校验
   * @parms
   * fileName 文件名称
   * coverAble 是否覆盖
   * schemaCode 模型编码
   */
  checkPackage(schemaCode: string, fileName: string, coverAble: boolean) {
    const vm: any = this;
    const params = {
      schemaCode,
      fileName,
      coverAble,
      isImportDataRule: this.isImportDataRule
    }
    this.checkApi(params).then((res: any) => {
      vm.isValidated = true;
      const data = res.data;
      if (res.errcode === 0) {
        if (data.result) {
          vm.subSchemaCodes === null ? vm.subSchemaCodes = data.subSchemaCodes : vm.subSchemaCodes; // 子表数据项
          vm.subSchemaNames = data.subSchemaNames; // 子表数据项名称
          vm.appFunctionModel = data.appFunctionModel; // 所在目录
          vm.appPackageModel = data.appPackageModel; // 所在应用

          vm.codeList = [{
            code: data.schemaCode,
            name: data.name,
            newCode: data.schemaCode,
            oldCode: data.schemaCode
          }]
          
          if(Array.isArray(data.bizForms)){
            data.bizForms.forEach((el:any) => {
              el.newCode = el.newCode || ''
            });
          }

          if(Array.isArray(data.workflows)){
            data.workflows.forEach((el:any) => {
              el.newCode = el.newCode || ''
            });
          }

          vm.bizFormsList = data.bizForms || [] // 表单
          vm.workflowsList = data.workflows || [] // 流程 

          vm.repeated = data.repeated || data.subSchemaCodes || data.repeatWorkflowCodes // 记录是否模型编码重复
          vm.isDelete = data.delete;  //记录是否对应的是回收站模型重复
          if(vm.repeated) {
            this.warnInfoList.repeatMsg = []
            if (this.isShowCodeRepeat) {
              if (this.isPackageModel && this.appPackageModel) {
                this.warnInfoList.repeatMsg.push(`是否覆盖已存在的业务模型编码？模型位置:${this.isDelete ? '回收站-' : ''}${this.appPackageModel.name}${this.appFunctionModel ? '-' + this.appFunctionModel.name : ''}`);
              } else if(this.appPackageModel) {
                this.warnInfoList.repeatMsg.push(`当前业务模型编码已存在，模型位置:${this.isDelete ? '回收站-' : ''}${this.appPackageModel.name}${this.appFunctionModel ? '-' + this.appFunctionModel.name : ''}`);
              }
            }
            if (this.isShowCodeRepeat && this.subSchemaCodes) {
              this.warnInfoList.repeatMsg.push(`${this.$t('languages.Apps.DocumentValidatedAndSheetcodeExistPlzModify')}`);
            }
            if (this.isPackageModel) {
              this.warnInfoList.repeatMsg.push(`${this.$t('languages.Apps.ImportWillReplaceDatamodelFormAndProcess')}`);
            }
            this.warnInfoList.repeatMsg.push(`${this.$t('languages.Apps.ImportWithModifiedCodeWillGenerateNewBizmodel')}`);
          }
          if(data.warningMsgs && data.warningMsgs.length !== 0){
            this.warnInfoList.warnMsg = data.warningMsgs
          }

          if (data.repeated || data.subSchemaCodes) { // 编码重复
            vm.validateStatus = FileValidateNS.FileValidateStatus.CodeRepeat;
            return;
          }

          if(data.warningMsgs && data.warningMsgs.length !== 0){
            this.warnInfoList.warnMsg = data.warningMsgs
            vm.validateStatus = FileValidateNS.FileValidateStatus.referCodesError;
            return;
          }

          if (data.errorType === 0) {
            this.validateStatus = FileValidateNS.FileValidateStatus.ValidateOk;
          }

        } else { // 校验失败
          this.validateStatus = FileValidateNS.FileValidateStatus.ValidateError;
          this.errorType = data.errorType;
          this.errorInfo = data.resultInfo;
          this.isShowUpdateCode = true;
        }
        // 文件校验成功
      } else {
        this.isShowUpdateCode = true;
        this.validateStatus = FileValidateNS.FileValidateStatus.ValidateError;
        this.errorType = res.errcode;
        this.errorInfo = res.errmsg;
        // 
      }
    })
  }

  resSetNewCode(){
    this.bizFormsList.forEach(el => el.newCode = '');
    this.sheetList = JSON.parse(JSON.stringify(this.oldSheetList))
    this.codeList[0].newCode = this.codeList[0].code
  }

  @Watch("subSchemaCodes")
  onSubSchemaCodesChange(v: any) {
    if (v && this.sheetList.length === 0) {
      for (const code in v) {
        this.sheetItemDate.set(code, {
          code,
          val: v[code],
          validateErrorTxt: ""
        });
      }
    }
  }

  @Watch("subSchemaNames")
  onSubSchemaNamesChange(v: any) {
    this.sheetList = []
    for (const key in v) {
      const sheetName = {
        name: v[key]
      }
      const sheetObj = Object.assign(this.sheetItemDate.get(key), sheetName);
      sheetObj.newCode = sheetObj.newCode || sheetObj.code
      this.sheetList.push(sheetObj);
    }
    this.oldSheetList = JSON.parse(JSON.stringify(this.sheetList))
  }

  /**
   * 关闭弹窗
   */
  handleCancel() {
    this.$emit('handleCancel');
  }

   /**
   * 修改编码
   */
  updateCode() {
    this.canSave = false
    this.isShowUpdateCode = true
  }

  /**
   * 修改编码界面如果有输入变化就显示保存并返回按钮
   */
  inputChange(list: any) {
    this.canSave = true
    
    // this.codeList = list.codeList
    // this.sheetList = list.sheetList
    // this.bizFormsList = list.bizFormsList
    // this.workflowsList = list.workflowsList
  }

  /**
   * 修改编码界面返回
   */
  returnClick(){ 
    this.isShowUpdateCode = false
    this.resSetNewCode()
  }

  returnAndSaveClick(){ // 保存并返回
    this.$nextTick( () => {
      this.modifySchemaCodesImport()
    })
  }

  /**
   * 修改编码导入
   */
  modifySchemaCodesImport() {
    this.oldSheetList = JSON.parse(JSON.stringify(this.sheetList))


    const backData: any = {};
    this.sheetList.forEach((item: any) => {
      backData[item.code] = item.newCode;
    });

    this.subSchemaCodes = Object.assign(this.subSchemaCodes || {}, backData);

    let list:any = this.getCodeList()
    if(!list) return
    this.checkAndImport(this.codeList[0].newCode, this.fileName, false, this.isImportDataRule, true)
  }

  /**
   * 文件校验后直接导入
   * @parms
   * fileName 文件名称
   * coverAble 是否覆盖
   * schemaCode 模型编码
   */
  checkAndImport(schemaCode: string, fileName: string, coverAble: boolean, isImportDataRule: any, isChecked: boolean = false) {
    this.isShowUpdateCode = true;
    let map: any = this.subSchemaCodes;
    const vm: any = this;

    let workflowCodeChangedMap = {};
    this.workflowsList.map((el:any) => {
      if(el.newCode){
        workflowCodeChangedMap[el.workflowCode] = el.newCode
      }
    });
    const params = {
      schemaCode,
      fileName,
      coverAble,
      map,
      isImportDataRule: this.isImportDataRule,
      workflowCodeChangedMap
    }
    
    this.checkApi(params, isChecked).then((res: any) => {

      vm.isValidated = true;
      if (res.errcode === 0) {
        const data = res.data;
        vm.subSchemaCodes === null ? vm.subSchemaCodes = data.subSchemaCodes : vm.subSchemaCodes; // 子表数据项
        vm.subSchemaNames = data.subSchemaNames; // 子表数据项名称
        vm.appFunctionModel = data.appFunctionModel; // 所在目录
        vm.appPackageModel = data.appPackageModel; // 所在应用
        vm.isDelete = data.delete;
        
        if (data.result) {
          this.repeated = data.repeated || data.subSchemaCodes || data.repeatWorkflowCodes
          if(data.repeated || data.subSchemaCodes || data.repeatWorkflowCodes){
            if(data.repeatNodeType === 'BizModel') {
              (this.$refs.updateCode as any).tabClick('1')
            }else if(data.subSchemaCodes) {
              (this.$refs.updateCode as any).tabClick('2')
            }else if(data.repeatWorkflowCodes) {
              (this.$refs.updateCode as any).tabClick('4')
            }
            this.$message.error('检测到以下新编码与系统中已存在的编码重复，请重新修改');
          }
          else {
            this.isShowUpdateCode = false
            if(data.warningMsgs && data.warningMsgs.length !== 0){
              vm.warnInfoList.warnMsg = data.warningMsgs
              vm.validateStatus = FileValidateNS.FileValidateStatus.referCodesError;
              this.codeList[0].code = this.codeList[0].newCode
              return;
            }
          }

          if(data.errorType === 0) {
            this.validateStatus = FileValidateNS.FileValidateStatus.ValidateOk;
            this.codeList[0].code = this.codeList[0].newCode
          }
        } else { // 校验错误直接弹出错误
          this.$message.error(data.errmsg)
        }
      } else{
        this.$message.error(res.errmsg)
      }
    })
  }

  checkApi(params: any, isChecked:boolean = false) {
    return new Promise((resolve, reject) => {
      AppsApi.check_package_new(params).then((res: any) => {
        resolve(res);
      })
    });
  }

  nextStep() {
    this.$emit('nextStep', {
      subSchemaCodes: this.subSchemaCodes,
      workflowsList: this.workflowsList,
      bizFormsList: this.bizFormsList,
      schemaCode: this.codeList[0].newCode,
      coverAble: this.isCoverable,
      isImportDataRule: this.isImportDataRule,
    })
  }

  prevStep() {
    this.$emit('prevStep')
  }

  importAndCover() {
    //this.checkAndImport('',this.fileName,true)
    /* 只有当点击导入并覆盖按钮且errorType为7时才弹窗 */
    this.isCoverable = true;
    if(this.warnInfoList.warnMsg && this.warnInfoList.warnMsg.length === 0)
      this.doImport()
  }

  doImport() {
    this.nextStep()
  }

  get showCover () {
    // console.log(this.appPackageModel, 'this.appPackageModel');
    if (this.appPackageModel) {
      return this.$route.params.appCode === this.appPackageModel.code && !this.isShowUpdateCode
    }
    return false;
  }
}
</script>

<style lang="less">
.file-validate {
  .validate-box {
    .file-status {
      &.repeat {
        display: block;
        height: 40px;
        background: #FFFBE6;
        border-radius: 4px;
        border: 1px solid #FFE58F;
        padding-left: 8px;
        .file-status-txt {
          font-size: 14px;
          line-height: 40px;
          height: 22px;
          color: rgba(0, 0, 0, 0.65);
          font-weight: 400;
        }
        span {
          display: inline;
        }
        & > div {
          margin-top: 10px;
          margin-left: 26px;
        }
        .high-light {
          color: @primary-color;
        }
      }
      display: flex;
      justify-content: flex-start;
      align-items: center;
      &-icon {
        color: @primary-color;
        font-size: 18px;
        &.error {
          color: #f5222d;
        }
      }
      &-warn {
        color: #faad14;
        transform: scale(0.75);
        display: inline-block;
      }
      &-txt {
        font-size: 16px;
        font-weight: bold;
        color: rgba(0, 0, 0, 0.85);
        margin-left: 8px;
        word-break: break-all;
      }
    }

    .validate-warn {
      width: 488px;
      margin-left: 8px;
      margin-top: 8px;
      padding: 8px;
      color: #f4454e;
      background: rgba(255, 163, 168, 0.06);
      border-radius: 4px;
      border: 1px solid rgba(245, 34, 45, 0.08);
    }
    .file-content {
      &.approved {
        margin-top: 24px;
      }
      &.repeated {
        margin-top: 14px;
      }
      &.error {
        margin-top: 16px;
      }
      &-hint {
        color: rgba(0, 0, 0, 0.45);
        font-size: 12px;
        line-height: 22px;
      }
      &-error {
        & > ul {
          padding: 8px;
          background: rgba(245, 34, 45, 0.06);
          border-radius: 4px;
          border: 1px solid rgba(245, 34, 45, 0.08);
        }
      }
      & .model-info {
        &.update-code {
          max-height: 145px;
          overflow: scroll;
        }
        & .model-item {
          margin-bottom: 20px;
          position: relative;
          &:last-of-type {
            margin-bottom: 0;
          }
          label {
            i {
              float: left;
            }
            color: rgba(0, 0, 0, 0.65);
            margin-right: 12px;
            display: inline-block;
            width: 108px;
            line-height: 32px;
            span.title {
              float: left;
              width: 88px;
              white-space: nowrap;
              text-overflow: ellipsis;
              overflow: hidden;
              margin-left: 0;
              line-height: 32px;
            }
          }
          & span {
            margin-left: 20px;
          }
          & input {
            width: 375px;
            &.error-input {
              border: 1px solid #f5222d;
              box-shadow: unset;
            }
          }
          & p.warn-txt {
            color: rgba(0, 0, 0, 0.65);
            font-size: 12px;
            line-height: 20px;
            text-indent: 120px;
          }
        }
      }
    }
  }
}
p.error-txt {
  color: #f5222d;
  text-align: left;
  margin-bottom: 0;
  // position: absolute;
}
.validate-msg {
  padding-left: 38px;
  font-size: 14px;
  font-family: PingFang-SC-Regular;
  font-weight: 400;
  color: rgba(0, 0, 0, 0.85);
  line-height: 22px;
}

.validate-icon-error {
  color: rgba(245, 154, 35, 1);
}
.validate-msg {
  margin-left: -12px;
  margin-bottom: 24px;
  ul {
    margin-top: 10px;
    padding: 8px;
    border-radius: 4px;
  }
  &.err {
    ul {
      font-size: 12px;
      line-height: 24px;
      background-color: rgba(245, 34, 45, 0.1);
      border: 1px solid rgba(245, 34, 45, 0.1);
    }
  }
  &.warn {
    ul {
      background-color: rgba(245, 245, 245, 1);
      border: 1px solid rgba(191, 191, 191, 0.16);
    }
  }
  .validate-title {
    padding-left: 8px;
  }
}
</style>
